package com.redteam.data.dao;

import com.redteam.data.beans.CharterPilot;
import com.redteam.data.dao.interfaces.DAO;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

/**
 * DAO for the CharterPilot class
 *
 * @author Steven Lawton
 * @version 1.0
 */
public class CharterPilotDAO extends AbstractDAO implements DAO {

    private static CharterPilotDAO dao;
    private static DataSource ds;
    private final String tableName;

    static {
        dao = new CharterPilotDAO();
    }

    /**
     * Returns the instance of this DAO.
     *
     * @return Singleton instance for use
     */
    public static CharterPilotDAO getInstance() {
        return dao;
    }

    private CharterPilotDAO() {
        getDataSource();
        this.tableName = "HIGHFLIERS.PERSONS";
    }

    /**
     * Returns the
     * <code>DataSource</code> for this DAO
     *
     * @return the
     * <code>DataSource</code> for this DAO
     */
    @Override
    public DataSource getDS() {
        return CharterPilotDAO.ds;
    }

    private void getDataSource() {
        try {
            InitialContext ic = new InitialContext();
            ds = (DataSource) ic.lookup("java:comp/env/jdbc/redteam");

        } catch (NamingException ex) {
            Logger.getLogger(CharterPilotDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Returns a
     * <code>CharterPilot</code> bean from
     * <code>ResultSet</code>
     *
     * @param rs
     * <code>ResultSet</code> returned from a query
     * @return
     * <code>CharterPilot</code> reference
     * @throws SQLException
     */
    @Override
    public CharterPilot getObjectOut(ResultSet rs) throws SQLException {

        String endorsements = rs.getString("ENDORSEMENT");

        CharterPilot cp = new CharterPilot();
        cp.setId(rs.getLong("ID"));
        cp.setFirstName(rs.getString("FIRSTNAME"));
        cp.setMiddleName(rs.getString("MIDDLENAME"));
        cp.setLastName(rs.getString("LASTNAME"));
        cp.setStreet(rs.getString("STREET"));
        cp.setCity(rs.getString("CITY"));
        cp.setState(rs.getString("STATE"));
        cp.setZipCode(rs.getString("ZIPCODE"));
        cp.setEmail(rs.getString("EMAIL"));
        cp.setfBOId(rs.getLong("FBO_ID"));
        cp.setBirthDate(rs.getDate("BIRTHDATE"));
        cp.setHomePhone(rs.getString("HOMEPHONE"));
        cp.setCellPhone(rs.getString("CELLPHONE"));
        cp.setWorkPhone(rs.getString("WORKPHONE"));
        cp.setGender(rs.getString("GENDER"));
        cp.setFlightHours(rs.getInt("FLIGHT_HOURS"));
        cp.setDiscriminator(rs.getString("DISCRIMINATOR"));
        cp.setUsername(rs.getString("USER_NAME"));
        cp.setPassword(rs.getString("PASSWORD"));

        String[] endorsementArr = endorsements.split(",");
        List<String> endorsementList = new ArrayList();
        endorsementList.addAll(Arrays.asList(endorsementArr));
        cp.setEndorsements(endorsementList);

        return cp;
    }

    /**
     * Returns insert query for
     * <code>CharterPilot</code> provided
     *
     * @param objectToInsert
     * <code>CharterPilot</code> object to insert into database
     * @return query to insert
     */
    @Override
    public String buildInsertQuery(Object objectToInsert) {

        CharterPilot person = (CharterPilot) objectToInsert;
        List<String> endorsements = person.getEndorsements();

        StringBuilder delimitedEndorsements = new StringBuilder();
        for (String s : endorsements) {
            delimitedEndorsements.append(s).append(",");
        }
        StringBuilder sb = new StringBuilder();
        sb.append("INSERT INTO ").append(this.getTableName());
        sb.append("(FIRSTNAME,MIDDLENAME,LASTNAME,STREET,CITY,STATE,ZIPCODE,EMAIL,");
        sb.append("FBO_ID,BIRTHDATE,HOMEPHONE,CELLPHONE,WORKPHONE,GENDER,FLIGHT_HOURS,");
        sb.append("ENDORSEMENT,DISCRIMINATOR,USER_NAME,PASSWORD)");
        sb.append(" VALUES ('");
        sb.append(person.getFirstName()).append("','");
        sb.append(person.getMiddleName()).append("','");
        sb.append(person.getLastName()).append("','");
        sb.append(person.getStreet()).append("','");
        sb.append(person.getCity()).append("','");
        sb.append(person.getState()).append("','");
        sb.append(person.getZipCode()).append("','");
        sb.append(person.getEmail()).append("',");
        sb.append(person.getfBOId()).append(",'");
        sb.append(person.getBirthDate()).append("','");
        sb.append(person.getHomePhone()).append("','");
        sb.append(person.getCellPhone()).append("','");
        sb.append(person.getWorkPhone()).append("','");
        sb.append(person.getGender()).append("',");
        sb.append(person.getFlightHours()).append(",'");
        sb.append(delimitedEndorsements).append("','");
        sb.append(person.getDiscriminator()).append("','");
        sb.append(person.getUsername()).append("','");
        sb.append(person.getPassword()).append("')");

        return new String(sb);
    }

    /**
     * Returns update query for
     * <code>CharterPilot</code> provided
     *
     * @param objectToUpdate
     * <code>CharterPilot</code> object to update in the database
     * @return query to update
     */
    @Override
    public String buildUpdateQuery(Object objectToUpdate) {

        CharterPilot person = (CharterPilot) objectToUpdate;
        List<String> endorsements = person.getEndorsements();

        StringBuilder delimitedEndorsements = new StringBuilder();
        for (String s : endorsements) {
            delimitedEndorsements.append(s).append(",");
        }
        StringBuilder sb = new StringBuilder("UPDATE ");
        sb.append(this.getTableName()).append(" SET FIRSTNAME='").append(person.getFirstName());
        sb.append("',MIDDLENAME='").append(person.getMiddleName());
        sb.append("',LASTNAME='").append(person.getLastName()).append("',STREET='");
        sb.append(person.getStreet()).append("',CITY='").append(person.getCity());
        sb.append("',STATE='").append(person.getState()).append("',ZIPCODE='");
        sb.append(person.getZipCode()).append("',EMAIL='").append(person.getEmail());
        sb.append("',FBO_ID=").append(person.getfBOId());
        sb.append(",BIRTHDATE='").append(person.getBirthDate());
        sb.append("',HOMEPHONE='").append(person.getHomePhone());
        sb.append("',CELLPHONE='").append(person.getCellPhone());
        sb.append("',WORKPHONE='").append(person.getWorkPhone());
        sb.append("',GENDER='").append(person.getGender());
        sb.append("',FLIGHT_HOURS=").append(person.getFlightHours());
        sb.append(",DISCRIMINATOR='").append(person.getDiscriminator());
        sb.append("',ENDORSEMENT='").append(delimitedEndorsements);
        sb.append("',USER_NAME='").append(person.getUsername());
        sb.append("',PASSWORD='").append(person.getPassword());
        sb.append("' WHERE ID= ").append(person.getId());

        return new String(sb);
    }

    /**
     * Returns the ID based on the <code>Object</code>
     *
     * @param obj reference to an <code>CharterPilot</code>
     * @return id of specified <code>CharterPilot</code>
     */
    @Override
    public long getObjectId(Object obj) {
        CharterPilot instructor = (CharterPilot) obj;
        return instructor.getId();
    }

    /** {@inheritDoc} */
    @Override
    public String getTableName() {
        return this.tableName;
    }

    /** {@inheritDoc} */
    @Override
    public List<Object> getAll() throws SQLException{
        return getAll( "charterPilot" );
    }

    /** {@inheritDoc} */
    @Override
    public Object getSingle( long id ) throws SQLException {
        return getSingle( id, "charterPilot" );
    }
}
